package com.infinitus.activity.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.aliyun.mns.client.CloudAccount;
import com.aliyun.mns.client.CloudTopic;
import com.aliyun.mns.client.MNSClient;
import com.aliyun.mns.common.ServiceException;
import com.aliyun.mns.model.BatchSmsAttributes;
import com.aliyun.mns.model.MessageAttributes;
import com.aliyun.mns.model.RawTopicMessage;
import com.aliyun.mns.model.TopicMessage;
/**
 * @create: 2019/1/9
 * @desc:
 */
@Component
public class PublishSms {
    // 阿里云AccessId
    @Value("${aliyun.sms.accessId}")
    private String accessId;

    // 阿里云AccessKey
    @Value("${aliyun.sms.accessKey}")
    private String accessKey;

    // 访问MNS服务的接入的公网地址
    @Value("${aliyun.sms.mnsEndpoint}")
    private String mnsEndpoint;

    // 短信专用主题
    @Value("${aliyun.sms.topic}")
    private String topic;

    // 短信签名
    @Value("${aliyun.sms.signName}")
    private String signName;

    // 随机数
    private int min = 100000;
    private int max = 999999;

    CloudTopic cloudTopic;

    MNSClient client;

    @PostConstruct
    private void init(){
        /**
         * Step 1. 获取主题引用
         */
        CloudAccount account = new CloudAccount(accessId, accessKey, mnsEndpoint);
        client = account.getMNSClient();
        cloudTopic = client.getTopicRef(topic);
    }

    @PreDestroy
    private void destroy(){
        client.close();
    }

    /**
     *  获取6位随机数
     * @return 6位随机数
     */
    public String get6Random() {
        int randNum = min + (int)(Math.random() * ((max - min) + 1));
        return String.valueOf(randNum);
    }

    /**
     * 给指定的手机发送短信:
     * 		如果为手机号码为null, 则抛出IllegalArgumentException异常.
     * @param phone 指定的手机号码
     * @param templateCode 阿里云短信模板
     * @param params 短信模板中的变量
     */
    public Map<String, String> sendSms(String phone, String templateCode, Map<String, String> params) {

        ArrayList<String> phoneList = new ArrayList<>();
        phoneList.add(phone);

        return this.sendSms(phoneList, templateCode, params);
    }


    /**
     * 给指定的手机群发发送短信, 群发信息的内容是一样的:
     * 		如果手机号码集为null或者size为0, 则抛出IllegalArgumentException异常.
     * @param phones 指定的手机号码集
     * @param templateCode 阿里云短信模板
     * @param params 短信模板中的变量(key)与值(value)
     * eq:
     * 		短信模板: “验证码${code}，您正在进行${product}身份验证，打死不要告诉别人哦！”
     *
     * 		@param phones: ["13888888888","13666666666"]
     * 		@param params: {"code":"123456","product":"alidayu"}
     */
    public Map<String, String> sendSms(List<String> phones, String templateCode, Map<String, String> params) {
        // 判断手机号码集是否为null或者没有手机号
        if (ParamAssert.isNull(phones) || phones.size() == 0) {
            throw new IllegalArgumentException("手机号码集不能为空!");
        }

        /**
         * Step 2. 设置SMS消息体（必须）
         *
         * 注：目前暂时不支持消息内容为空，需要指定消息内容，不为空即可。
         */
        RawTopicMessage msg = new RawTopicMessage();
        msg.setMessageBody("sms-message");
        /**
         * Step 3. 生成SMS消息属性
         */
        MessageAttributes messageAttributes = new MessageAttributes();
        BatchSmsAttributes batchSmsAttributes = new BatchSmsAttributes();

        // 3.1 设置发送短信的签名（SMSSignName）
        batchSmsAttributes.setFreeSignName(signName);
        // 3.2 设置发送短信使用的模板（SMSTempateCode）
        batchSmsAttributes.setTemplateCode(templateCode);

        // 3.3 设置发送短信所使用的模板中参数对应的值（在短信模板中定义的，没有可以不用设置）
        BatchSmsAttributes.SmsReceiverParams smsReceiverParams = new BatchSmsAttributes.SmsReceiverParams();

        if (!ParamAssert.isNull(params)) {
            Set<String> keySet = params.keySet();
            for (String key : keySet) {
                smsReceiverParams.setParam(key, params.get(key));
            }
        }

        for (String phone : phones) {
            try {
                if (!ParamAssert.isPhone(phone)) {
                    continue;
                }
            } catch (Exception e) {
                continue;
            }
            // 3.4 增加接收短信的号码
            batchSmsAttributes.addSmsReceiver(phone, smsReceiverParams);
        }

        messageAttributes.setBatchSmsAttributes(batchSmsAttributes);

        // 响应数据
        Map<String, String> map = new HashMap<>();
        try {
            /**
             * Step 4. 发布SMS消息
             */
            TopicMessage ret = cloudTopic.publishMessage(msg, messageAttributes);

            // 封装响应数据
            map.put("code", "OK");
            map.put("messageId", ret.getMessageId());
            map.put("messageMD5", ret.getMessageBodyMD5());

        } catch (ServiceException se) {
            // 封装响应数据
            map.put("code", se.getErrorCode());
            map.put("requestId", se.getRequestId());
            map.put("message", se.getMessage());
        } catch (Exception e) {
            // 封装响应数据
            map.put("code", "500");
            map.put("message", e.getMessage());
        }

        return map;
    }
}